package com.example.hms.util;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class TokenInter implements HandlerInterceptor {
    private long refreshTime = 1000 * 60 * 60 * 3; // TOKEN过期时间为3小时


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器拦截完成，默认放行");
        // 从session中获取用户信息
        String userId = ((Integer) request.getSession().getAttribute("userId")).toString();
        Object userName = request.getSession().getAttribute("userName");
        Object roleName = request.getSession().getAttribute("roleName");

        //通过session中的用户信息校验确定用户是否登录
        // 验证用户是否已经登录
        if (userId != null && userName != null && roleName != null) {
            // 用户已登录，获取并验证Token
            HttpSession session = request.getSession();
            String token = (String) session.getAttribute("token");
            Map<String, Object> map = TokenUtil.checkToken(token);
            String userId1 = (String) map.get("userId");
            String roleName1 = (String) map.get("roleName");

            // 检查Token中的用户信息是否与Session中的信息一致
            if (userId1.equals(userId) && roleName1.equals(roleName)) {
                // 检查Token是否过期
                long time = (long) map.get("time");
                if (System.currentTimeMillis() - time > refreshTime) {
                    // Token过期，返回错误信息并拦截请求
                    returnJson(response, JSONCreate("用户信息已过期，请重新登录"));
                    return false;
                } else {
                    // Token未过期，放行请求
                    return true;
                }
            } else {
                // Token中的用户信息与Session不一致，拦截请求
                returnJson(response, JSONCreate("用户信息已过期，请重新登录"));
                return false;
            }
        } else {
            // 用户未登录，拦截请求并返回错误信息
            returnJson(response, JSONCreate("用户未登录"));
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("业务代码执行完毕");
        //创建session对象
            HttpSession session = request.getSession();
        //获取session中的用户信息
        int userId = (int) request.getSession().getAttribute("userId");
        Object userName = request.getSession().getAttribute("userName");
        Object roleName = request.getSession().getAttribute("roleName");
        //获取当前系统信息
        long time = (long) session.getAttribute("time");
        //通过用户信息和系统时间戳生成最新的TOKEN并存入session
        session.setAttribute("token",TokenUtil.getToken(userId+"",userName.toString(),roleName.toString(),time));
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("视图渲染完毕");
    }


    private void returnJson(HttpServletResponse response, String result) throws Exception {
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(result);

        } catch (IOException e) {
        } finally {  // 不管有没有报错都可以运行
            if (writer != null) {
                writer.close();
            }
        }
    }
//    返回类型信息 拦截之后不能返回信息  （生成报错信息，StringBuffer 随时增加或减少字符串）
    private String JSONCreate(String message){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("{\"code\":-1,\"message\":\"");
        stringBuffer.append(message);
        stringBuffer.append("\"}");
        return stringBuffer.toString();
    }


}